package com.example.demo.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;

/**
 * @author Liunh
 */
public class ApplicationContextUtil implements ApplicationContextAware {

    public volatile static ApplicationContext applicationContext;
    public volatile static ApplicationConstant constant;
    private static RequestContext requestContext;
    private static final ThreadLocal<ApplicationContextUtil> apLocal = new ThreadLocal<>();
    private HttpServletRequest request;
    private HttpServletResponse response;

    public static ApplicationContextUtil newInstan() {
        if (apLocal.get() == null) {
            ApplicationContextUtil applicationContextUtil = new ApplicationContextUtil();
            apLocal.set(applicationContextUtil);
            return applicationContextUtil;
        }
        return apLocal.get();
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }

    public static String getMessage(String code) {
        return requestContext.getMessage(code);
    }


    public synchronized void init(ApplicationConstant applicationConstant) {
        constant = applicationConstant;
    }

    public HttpSession getSession() {
        return this.getRequest().getSession();
    }

    public ServletContext getServletContext() {
        if (this.getSession() == null) {
            return null;
        }
        return this.getSession().getServletContext();
    }

    public Object getBean(String name) {
        if (this.getServletContext() == null) {
            return null;
        }
        Object bean = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext()).getBean(name);
        apLocal.remove();
        return bean;
    }

    public <T> T getBean(String name, Class<T> clazz) {
        if (this.getServletContext() == null) {
            return null;
        }
        T bean = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext()).getBean(name, clazz);
        apLocal.remove();
        return bean;
    }

    public HttpServletRequest getRequest() {
        if (this.request == null) {
            this.request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        }
        return this.request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
        requestContext = new RequestContext(request);
    }

    public HttpServletResponse getResponse() {
        return this.response;
    }

    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

}